package org.shangrila.bme.mb;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.model.SelectItem;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.event.RowEditEvent;
import org.shangrila.app.sys.cfg.AppInitInfo;
import org.shangrila.app.sys.shiro.SecUtil;
import org.shangrila.app.wfm.mb.WfmTaskMgrMB;
import org.shangrila.bme.eo.AppFileInfo;
import org.shangrila.bme.eo.BmeContPurch;
import org.shangrila.bme.eo.BmeContract;
import org.shangrila.bme.eo.BmeMaterial;
import org.shangrila.bme.eo.BmePurchDetail;
import org.shangrila.bme.eo.BmePurchOrder;
import org.shangrila.bme.eo.BmeSupplier;
import org.shangrila.bme.eo.BmeWfmService;
import org.shangrila.comm.dao.DbAccess;
import org.shangrila.comm.helper.DateHelper;
import org.shangrila.comm.helper.IDHelper;
import org.shangrila.wfm.core.WfmEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Named
@SessionScoped
public class PurchMB implements Serializable {
	private static final long serialVersionUID = -595146464217112L;
	private final Logger log = LoggerFactory.getLogger(this.getClass());

	@Inject
	private DbAccess db;
	@Inject
	BmeCommEntityService bmeCommEntityService; 
	@Inject
	private AttachUploadMB attachUploadMB;
	
    private BmePurchOrder io = new BmePurchOrder();//录入订单信息
    
	private List<BmePurchOrder> vop = new ArrayList<BmePurchOrder>(); //订单
	private List<BmePurchDetail> vod = new ArrayList<BmePurchDetail>(); //详情
	
	private BmePurchDetail selectedd = new BmePurchDetail();//录入以及选择详情信息
	
	private List<BmeContract> bmeContracts; 	
	private BmeContract selectedContract = new BmeContract(); 

	private List<BmeSupplier> bmeSuppliers; 	
	private BmeSupplier selectedSupplier = new BmeSupplier(); 

	private BmeMaterial selectedMaterial = new BmeMaterial(); 

	private List<BmeContPurch> bmeContPurches; 	
	private BmeContPurch selectedContPurch = new BmeContPurch(); 
	private List<BmeContPurch> selectedContPurches = new ArrayList<BmeContPurch>(); //多选采购清单


	//获取相关数据字典
	private List<SelectItem> itemsPurchStatus = AppInitInfo.getDropdownList("PurchStatus"); 

	private String operator;
	private String purchId="";
	private String contractName="";

	private String uploadedFile="";
	private String uploadedFileImage="";
	private boolean uploadFlag=false;

	//附件上传页面参数传递
	private String uploadForType="2";
	private String uploadForId="0";
	private String uploadForName="0";
	
	private String processName="wf_cgdd"; //采购订单流程

	@PostConstruct
    public void init() {
		log.info("@PostConstruct..."+this.getClass());
		try{
			operator = SecUtil.getCachedShiroUser().getUserno();
		}
		catch(Exception ex){
			operator="bme";
		}
		newIo();
		initdata();

    }
    
	//接收WFM参数
	public void initwfm() {
		WfmTaskMgrMB wfmTaskMgrMB = (WfmTaskMgrMB)AppInitInfo.findSessionBeanByName("wfmTaskMgrMB");
		if(null != wfmTaskMgrMB) {
			purchId = wfmTaskMgrMB.getSelectedTask().getServiceNo();
			log.info("initwfm-purch="+purchId);
			queryAction();
		}
	}
	
	 public void initdata() {
	    	//查找bmeCustomerService实例初始化下拉数据
			//BmeCommEntityService service = AppInitInfo.findMBeanByName("bmeCommEntityService",BmeCommEntityService.class);
			bmeSuppliers = bmeCommEntityService.getBmeSuppliers();
	    	bmeContracts = bmeCommEntityService.getBmeContracts();
	    	
	    	//把合同状态为3的合同提取出来
	    	List<BmeContract> bmeContractsNew=new ArrayList<>();
	    	for(int i=0;i<bmeContracts.size();i++) {
	    		if("3".equals(bmeContracts.get(i).getStatus())) {
	    			bmeContractsNew.add(bmeContracts.get(i));
	    		}
	    	}
	    	bmeContracts=bmeContractsNew;
	 }

    public void newIo() {
    	initdata();
    	io = new BmePurchOrder();
    	io.setStatus("1");
    	io.setId(IDHelper.genStrID(20));
    	vop = new ArrayList<BmePurchOrder>();
    	vod = new ArrayList<BmePurchDetail>();
    	attachUploadMB.setVoList(new ArrayList<AppFileInfo>());
    	attachUploadMB.setUploadedFileImage("");
    }    

	public String nullAction() {
		return null;
	}

	public String wfmAction() {
		if(!validDetailAction()) {
			return null;
		}
		//1=制单状态才能提交
		if(null==io.getId() || !"1".equals(io.getStatus())) {
			AppInitInfo.showMessage("提交流程失败", "单据编号为空或者状态不正确");
			return null;
		}
		//提交流程
		//流程参数
		Map<String, Object> args = new HashMap<String, Object>();	
		//业务编号作为WFM实例的serviceNo
		args.put(AppInitInfo.APP_BUSINESS_NO, io.getId());  	
		//下一个流程节点处理工号，all可以代表所有操作工号，只要有此流程角色即可
		args.put(AppInitInfo.APP_OPERATOR,"all");			
		args.put(AppInitInfo.APP_BUSINESS_TYPE, uploadForType);		   //自定义业务参数：业务类型
		//operator="bme";  					   //发起本流程任务操作的工号

		WfmEngine engine = new WfmEngine();//流程引擎
		//启动流程实例
		engine.startService(engine.getWfmdao().findProcessByName(processName).get(0), operator, args);
		
		//填写业务流程日志信息
		BmeWfmService bws = new BmeWfmService();
		bws.setId(IDHelper.genStrID(24));
		bws.setBusinessId(io.getId());
		bws.setBusinessType(uploadForType);
		bws.setCreateTime(new Date());
		bws.setOperator(operator);
		bws.setProcessName(processName);
		bws.setServiceNo(io.getId()); //业务编号作为WFM实例的serviceNo
		io.setStatus("2"); //审核中
		db.begin();
		db.insert(bws);
		db.update(io);
		db.commit();
		AppInitInfo.showMessage("订单提交流程", "处理成功");
		return null;
	}
	
    //查询信息
	public String queryAction() {		
		String sql = "SELECT m FROM BmePurchOrder m WHERE m.id=?1 OR m.contName=?2";
		vop = db.findBySql(sql, new Object[]{purchId,contractName });
		if(vop.size()>0) {
			io = vop.get(0);
			selectedContract = io.getBmeContract();
			selectedSupplier = io.getBmeSupplier();
			bmeContPurches = selectedContract.getBmeContPurches();
			vod = io.getBmePurchDetails();
			//附件
			uploadForId=io.getId();
			uploadForName=io.getContName();
			sql="SELECT m FROM AppFileInfo m WHERE m.forId=?1 and m.forType=?2";
			attachUploadMB.setVoList(db.findBySql(sql, new Object[]{io.getId(),uploadForType}));

		}
		else {
			io = new BmePurchOrder();
			vod = new ArrayList<BmePurchDetail>();
		}
				
		return null;
	}
	
	//新增订单
    public void onAddOrder() {   
    	newIo();
        AppInitInfo.showMessage("新增订单", "处理成功");       
    }
    
    //保存订单
	public String saveAction() {		
		db.beginTransaction();
		io.setBmeContract(selectedContract);
		io.setBmeSupplier(selectedSupplier);
		io.setContName(selectedContract.getName());
		io.setCreateTime(new Date());
		io.setOperator(operator);
		db.insert(io);
		db.commitTransaction();
		
		AppInitInfo.showMessage("订单录入", "处理成功");
		uploadForId=io.getId();
		uploadForName=io.getContName();
		return null;
	}
	
	//验证详单操作的有效性
	public boolean validDetailAction(){
		if(null==io.getCreateTime()) {
			AppInitInfo.showMessage("warn","操作无效", "请确保单据主体信息已经保存");
			return false;
		}
		else
			return true;
	}	
	
    //清单选择录入保存
	public String saveDetail() {
		if(!validDetailAction()) {
			return null;
		}
		List<BmePurchDetail> bpdList = new ArrayList<BmePurchDetail>();
		for(BmeContPurch bcp:selectedContPurches) {
			selectedd = new BmePurchDetail();				
	     	selectedMaterial = bcp.getBmeMaterial();
	     	selectedd.setBmeMaterial(selectedMaterial);
	     	selectedd.setMdesc(selectedMaterial.getMdesc());
	     	selectedd.setMunit(selectedMaterial.getMunit());
	     	selectedd.setMprice(bcp.getPrice());
	     	selectedd.setMquantity(bcp.getQuantity());
	     	selectedd.setMamount(bcp.getAmount());
	     	selectedd.setAmount(bcp.getAmount());
	     	selectedd.setArea(bcp.getArea());
			selectedd.setId(IDHelper.genStrID(20));
			selectedd.setBmePurchOrder(io);
			selectedd.setBmeMaterial(selectedMaterial);
			
	     	selectedd.setProcessQuantity(bcp.getProcessQuantity());
	     	selectedd.setSpeci(bcp.getSpeci());
	     	selectedd.setProcessSpeci(bcp.getProcessSpeci());	     		
			selectedd.setProcessTeck(bcp.getProcessTeck());

			selectedd.setCreateTime(new Date());
			selectedd.setRequiredDate(DateHelper.strToDate(DateHelper.dateToStr(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd"));
			//selectedd.setRespDate(DateHelper.strToDate(DateHelper.dateToStr(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd"));
			selectedd.setOperator(operator);
			bpdList.add(selectedd);
		}		
		try {
			db.beginTransaction();
			for(BmePurchDetail bcp:bpdList) {
				db.insert(bcp);
			}
			db.commitTransaction();				
			vod.addAll(bpdList);
			io.setBmePurchDetails(vod);
			AppInitInfo.showMessage("新增详情录入", "处理成功");
			selectedContPurches=null;
	
		}catch(Exception e) {			
			AppInitInfo.showMessage("error","新增详情失败", "请确保单据主体信息已经保存");
			log.error(e.getLocalizedMessage());
			try {
				db.rollbackTransaction();
			}catch(Exception ex) {	}
		}
		return null;
	}
	
	//根据规格、数量生成加工数量片：数量/规格（600*400）：10/（0.600*0.400）
	public static BigDecimal calcProcessQuantity(BigDecimal b,String speci){
		try {
	    	double q = b.doubleValue();
	    	int i = speci.indexOf("*");
	    	double d1=Integer.parseInt(speci.substring(0, i))/1000.00;
	    	double d2=Integer.parseInt(speci.substring(i+1))/1000.00;
	    	//double k=(double)Math.round(q/(d1*d2)*100)/100; //double保持2位小数
	    	return new BigDecimal(q/(d1*d2)).setScale(0, BigDecimal.ROUND_HALF_UP);//BigDecimal保持0位小数
    	}catch(Exception e) {
    		return new BigDecimal(0);
    	}
	}
    
	//genOrderAmount 生成订单金额+修改合同采购清单已下单量
    public void genOrderAmount() {
		if(!validDetailAction()) {
			return ;
		}
		//从BmePurchDetail表生成BmePurchOrder的amount数据，并且修改BmeContPurch对应的已下单数
		BigDecimal sumMoney = new BigDecimal(0);
		db.beginTransaction();
		for(BmePurchDetail bpd:vod) {
			sumMoney = sumMoney.add(null==bpd.getAmount() ? new BigDecimal(0) : bpd.getAmount());//订单金额
			for(BmeContPurch bcp:bmeContPurches) { //修改BmeContPurch对应的已下单数
				if(bcp.getBmeMaterial().getId().equalsIgnoreCase(bpd.getBmeMaterial().getId())) {
					bcp.setQtyOrdered(bpd.getMquantity());
					db.update(bcp);					
				}
			}
		}
		io.setAmount(sumMoney.setScale(2,BigDecimal.ROUND_HALF_UP));
		db.update(io);
		db.commitTransaction();
		AppInitInfo.showMessage("生成订单金额", "处理成功");
    } 
    
	//删除
    public String delDetail() {
    	vod.remove(selectedd);
		db.beginTransaction();
		db.delete(selectedd);
		db.commitTransaction();

        AppInitInfo.showMessage("删除记录", "处理成功");
        return null;
    }
	
    public void onSelectedContract() {
    	bmeContPurches = selectedContract.getBmeContPurches();
    	io.setShippingAddress(selectedContract.getShippingAddress());
    	for(BmeSupplier bs : bmeSuppliers) {
    		if(bs.getId().endsWith(selectedContract.getSupplierId())) {
    			selectedSupplier = bs;
    			break;
    		}
    	}
    } 
    
	//编辑
    public void onRowEdit(RowEditEvent event) {
    	selectedd = vod.get(vod.indexOf((BmePurchDetail) event.getObject()));
    	//数量、数量片的彼此转换
    	BigDecimal processQuantity = selectedd.getProcessQuantity();
    	BigDecimal mquantity = selectedd.getMquantity();
    	String mmodel = selectedd.getBmeMaterial().getMmodel();
    	int i = mmodel.indexOf("*");
    	double m1=Integer.parseInt(mmodel.substring(0,i))/1000.00;
    	double m2=Integer.parseInt(mmodel.substring(i+1))/1000.00;
    	BigDecimal decimal = new BigDecimal(m1*m2);
    	
    	if(processQuantity==null) {
    		AppInitInfo.showMessage("数量片为空", "无法换算为数量");
    	}else {
    		mquantity=decimal.multiply(processQuantity).setScale(4,BigDecimal.ROUND_HALF_UP);
    	}
    	selectedd.setMquantity(mquantity); 
    	
    	/*
    	1.数量（㎡）=数量（片）*规格			
    	2.金额=数量（㎡）*单价			
    	3.运费总价=运费单价*数量（㎡）			
    	4.加工费=数量（片）*每片加工量（米）*加工单价			
    	5.总金额=金额+运费总价+加工费			
		*/
    	//物料Mamount=Mprice*Mquantity
     	selectedd.setMamount( (null==selectedd.getMprice() ? new BigDecimal(0) : selectedd.getMprice()).multiply((null==mquantity ? new BigDecimal(0) : mquantity)).setScale(2,BigDecimal.ROUND_HALF_UP) );
    	//运费Tamount=Tprice*Mquantity
     	selectedd.setTamount( (null==selectedd.getTprice() ? new BigDecimal(0) : selectedd.getTprice()).multiply((null==mquantity ? new BigDecimal(0) : mquantity)).setScale(2,BigDecimal.ROUND_HALF_UP) );
     	//加工ProcessAmount=ProcessQuantity*ProcessPrice*ProcessFactor
     	selectedd.setProcessAmount(
     			(null==selectedd.getProcessPrice() ? new BigDecimal(0) : selectedd.getProcessPrice()).multiply(
     					(null==selectedd.getProcessFactor() ? new BigDecimal(0) : selectedd.getProcessFactor())).multiply(
     							null==selectedd.getProcessQuantity() ? new BigDecimal(0) : selectedd.getProcessQuantity()).setScale(2,BigDecimal.ROUND_HALF_UP)	);
     	//总费用Amount=Mamount+Tamount+ProcessAmount
     	selectedd.setAmount( (null==selectedd.getMamount() ? new BigDecimal(0) : selectedd.getMamount()).add((null==selectedd.getTamount() ? new BigDecimal(0) : selectedd.getTamount())).add((null==selectedd.getProcessAmount() ? new BigDecimal(0) : selectedd.getProcessAmount())).setScale(2,BigDecimal.ROUND_HALF_UP) );
     		
    	db.beginTransaction();
    	db.update(selectedd);
    	db.commitTransaction();
    	AppInitInfo.showMessage("清单修改", "处理成功");
    	
    	
    }
    
    public void onRowCancel(RowEditEvent event) {
    	AppInitInfo.showMessage("取消修改", "处理成功");
    }
    
	public BmePurchOrder getIo() {
		return io;
	}

	public void setIo(BmePurchOrder io) {
		this.io = io;
	}

	public List<BmePurchOrder> getVop() {
		return vop;
	}

	public void setVop(List<BmePurchOrder> vop) {
		this.vop = vop;
	}

	public List<BmePurchDetail> getVod() {
		return vod;
	}

	public void setVod(List<BmePurchDetail> vod) {
		this.vod = vod;
	}

	public BmePurchDetail getSelectedd() {
		return selectedd;
	}

	public void setSelectedd(BmePurchDetail selectedd) {
		this.selectedd = selectedd;
	}

	public List<BmeSupplier> getBmeSuppliers() {
		return bmeSuppliers;
	}

	public void setBmeSuppliers(List<BmeSupplier> bmeSuppliers) {
		this.bmeSuppliers = bmeSuppliers;
	}

	public BmeSupplier getSelectedSupplier() {
		return selectedSupplier;
	}

	public void setSelectedSupplier(BmeSupplier selectedSupplier) {
		this.selectedSupplier = selectedSupplier;
	}

	public BmeMaterial getSelectedMaterial() {
		return selectedMaterial;
	}

	public void setSelectedMaterial(BmeMaterial selectedMaterial) {
		this.selectedMaterial = selectedMaterial;
	}

	public List<SelectItem> getItemsPurchStatus() {
		return itemsPurchStatus;
	}

	public void setItemsPurchStatus(List<SelectItem> itemsPurchStatus) {
		this.itemsPurchStatus = itemsPurchStatus;
	}

	public String getPurchId() {
		return purchId;
	}

	public void setPurchId(String purchId) {
		this.purchId = purchId;
	}

	public String getContractName() {
		return contractName;
	}

	public void setContractName(String contractName) {
		this.contractName = contractName;
	}

	public String getUploadedFile() {
		return uploadedFile;
	}

	public void setUploadedFile(String uploadedFile) {
		this.uploadedFile = uploadedFile;
	}

	public String getUploadedFileImage() {
		return uploadedFileImage;
	}

	public void setUploadedFileImage(String uploadedFileImage) {
		this.uploadedFileImage = uploadedFileImage;
	}

	public BmeContract getSelectedContract() {
		return selectedContract;
	}

	public void setSelectedContract(BmeContract selectedContract) {
		this.selectedContract = selectedContract;
	}

	public List<BmeContract> getBmeContracts() {
		return bmeContracts;
	}

	public void setBmeContracts(List<BmeContract> bmeContracts) {
		this.bmeContracts = bmeContracts;
	}

	public String getUploadForType() {
		return uploadForType;
	}

	public void setUploadForType(String uploadForType) {
		this.uploadForType = uploadForType;
	}

	public String getUploadForId() {
		return uploadForId;
	}

	public void setUploadForId(String uploadForId) {
		this.uploadForId = uploadForId;
	}

	public String getUploadForName() {
		return uploadForName;
	}

	public void setUploadForName(String uploadForName) {
		this.uploadForName = uploadForName;
	}

	public List<BmeContPurch> getBmeContPurches() {
		return bmeContPurches;
	}

	public void setBmeContPurches(List<BmeContPurch> bmeContPurches) {
		this.bmeContPurches = bmeContPurches;
	}

	public BmeContPurch getSelectedContPurch() {
		return selectedContPurch;
	}

	public void setSelectedContPurch(BmeContPurch selectedContPurch) {
		this.selectedContPurch = selectedContPurch;
	}

	public boolean isUploadFlag() {
		return uploadFlag;
	}

	public void setUploadFlag(boolean uploadFlag) {
		this.uploadFlag = uploadFlag;
	}

	public List<BmeContPurch> getSelectedContPurches() {
		return selectedContPurches;
	}

	public void setSelectedContPurches(List<BmeContPurch> selectedContPurches) {
		this.selectedContPurches = selectedContPurches;
	}
	
}